#ifndef MAINWINDOW_H
#define MAINWINDOW_H

//MY LIBRARIES
#include <ptz_controller.h>
#include <ptcalibration.h>
#include <processmaster.h>
#include <processslave.h>

#include <QtGui>



#include "imglib_VideoSource.h"
#include "eventCollector.h"


//LIBRARIES
#include <iostream>
#include <fstream>


//QT
#include <QMainWindow>
#include <QtGui>

//IMAGELAB
#include "proclib_SourceManager.h"
#include "opencvsupport.h"
#include <imglib_VideoSource_JPGSequence.h>
#include <imglib_VideoOutput_JPGSequence.h>
//#include "proclib_axis_camera_stream.h"

//OPENCV
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

class QThreadEx : public QThread
{
protected:
    void run() { exec(); }
};

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    bool connectActions();
    void readSettings();
    void writeSettings();
private:
    Ui::MainWindow *ui;

    //COMPONENTI DEL FORM

    //MdiArea
    QMdiArea *mdiArea;
    //QMdiArea *_mdiArea_PTZ;
    QMenu * m_pWindowMenu;
    QSignalMapper *windowMapper;




    // actions
    QAction* closeAct;
    QAction*closeAllAct;
    QAction*tileAct ;
    QAction*cascadeAct;
    QAction*nextAct;
    QAction*previousAct;
    QAction*separatorAct;
    QAction*aboutQtAct;

    //Bottoni
    QPushButton *_cmdStartDetector;
    QPushButton *_cmdStopDetector;
    QPushButton *_cmdGoToMasterPoint;
    QPushButton *_cmdGoToPoint;
    QPushButton *_cmdGoToHome;
    QPushButton *_cmdCreateController;
    QPushButton *_cmdOpenHomography;
    QPushButton *_cmdOpenCalibration;
    QPushButton *_cmdGOList;
    QPushButton *_cmdSaveMasterView;
    QPushButton *_cmdSaveSlaveView;
    QPushButton *_cmdCreateHomography;
    QPushButton *_cmdCreateCalibration;

    QPushButton *_cmdThreadOn;
    QPushButton *_cmdThreadOff;

    QPushButton *_cmdTiltUp;
    QPushButton *_cmdTiltDown;
    QPushButton *_cmdPanLeft;
    QPushButton *_cmdPanRight;
    QPushButton *_cmdZoomAdd;
    QPushButton *_cmdZoomSub;

    //Text Area
    QTextBrowser *_AreaOutput;
    QTextBrowser *_AreaOutputSlave;


    //ImageWindows
    CImageWindow *_WindowsMaster;
    CImageWindow *_WindowsSlave;

    //ComboBox
    QComboBox *_ListHomePosition;

    //TextLine
    QLineEdit *_txtX;
    QLineEdit *_txtY;
    QLineEdit *_txtZoom;

    QLineEdit *_txtDiscardDelay;

    //CheckBox
    QCheckBox *_chkFastSift;

    //LABEL
    QLabel *_lblHomoOK;
    QLabel *_lblCaliOK;
    QLabel *_lblControlOK;
    QLabel *_lblBlockMasterOK;
    QLabel *_lblBlockSlaveOK;
    QLabel *_lblHomographyCreated;
    QLabel *_lblPTTransformCreated;
    QLabel *_lblSetHome;


    //VARIBILI VARIE

    //Posizione di Home
    CCameraPosition _Home;
    //Nome della home
    CStr _HomeName;

    //Sorgenti Video
    CSourceManager *_Master;
    CSourceManager *_Slave;

    //Gestore Movimento PTZ
    PTZ_Controller *_ControllerPTZ;

    //Gestore Calibrazione PT
    PTCalibration *_CalibrationPTZ;

    //Matrici
    cv::Mat _matrixHomography;
    cv::Mat _matrixCalibration;

    //THREAD
    ProcessMaster *_procMaster;
    ProcessSlave *_procSlave;
    QThreadEx *_thProducer;
    QThreadEx *_thConsumer;


    //Recorder Video
    QString _nameFile;  //Nome del file
    cv::VideoWriter _videoOutput;   //Registratore video

    //Timer
    QTimer *_Delay;

    //Segnali Booleani per Azioni
    bool _SaveMasterView;
    bool _SaveSlaveView;

    bool _showMasterFrame;
    bool _showSlaveFrame;

    //Immagini da cui ricavare l'omografia
    CImageRGB _detectorView;
    CImageRGB _PTZView;

    //Controlli
    bool _HomeSet;
    bool _HomeRead;
    bool _ControllerSet;

    //Variabili StateMachine
    vector<QPoint> _vettCentresScan;

    bool _bMasterScan;
    bool _bSlaveScan;



private slots:

    //Slot per la gestione dei frame delle sorgenti video
    void sl_frameMaster(CImageRGB *frame);
    void sl_frameSlave(CImageRGB *frame);

    //Slot per inzializzare il controller
    void sl_clickOpenHomography();
    void sl_clickOpenCalibration();
    void sl_CreateControllerHome();

    //Slot per creare la lista dei preset
    void sl_CreateListBox();

    //Setta la Home
    void sl_setHome();

    //Slot per il movimento
    void sl_MovePTZfromMaster();
    void sl_MoveList();
    void sl_MovePoint();

    void sl_MoveCameraPanLeft();
    void sl_MoveCameraPanRight();
    void sl_MoveCameraTiltUp();
    void sl_MoveCameraTiltDown();
    void sl_MoveCameraZoomAdd();
    void sl_MoveCameraZoomSub();

    //Slot per l'inizializzazione delle matrici di calibrazione
    void sl_CaptureMaster();
    void sl_CaptureSlave();
    void sl_CreateHomography();
    void sl_CreateCalibration();

    //Cambio label
    void sl_SetHomograhyCreatedLabel();
    void sl_SetPTTransformCreatedLabel();

    //StateMachine
    void sl_WaitScanSalveFrame();
    void sl_Repositiction();
    void sl_State0_NormaleMode();
    void sl_State1_MasterDetectionMode();
    void sl_State2_SlaveDetectionMode();
    void sl_State3_Reposiction();

    //Thread
    void sl_GoThread();
    void sl_StopThread();

    //Stampe Output
    void sl_StampPoint(vector<PointTime>* foundPoint);
    void sl_StampPointSlave(vector<QPoint> *foundPoint);

    //Windows Management
    QWidget *activeMdiChild();

    QMdiSubWindow *findMdiChild(const QString &fileName);
    void setActiveSubWindow(QWidget *window);
    void updateWindowMenu();

protected:
        void closeEvent(QCloseEvent *event);
        QMdiArea *getMDIArea();
private:

    void GoMasterScan(CImageRGB *frame);
    void GoSlaveScan(CImageRGB *frame);
    void GeneralConnect();
    void GeneralDisconnect();
    void StateMachineConnect();
    void StateMachineDisconnect();
    void ThreadConnect();
    void ThreadDisconnect();



signals:
    void sign_SelectedFile();
    void sign_MasterScanComplete();
    void sign_SlaveScanComplete();
    void sign_ReposictionComplete();
};

#endif // MAINWINDOW_H
